package org.gwt.grin.client.util;

public class Color {

	public static final Color WHITE = new Color(255, 255, 255);
	public static final Color LIGHT_GRAY = new Color(192, 192, 192);
	public static final Color GRAY = new Color(128, 128, 128);
	public static final Color DARK_GRAY = new Color(64, 64, 64);
	public static final Color BLACK = new Color(0, 0, 0);
	public static final Color RED = new Color(255, 0, 0);
	public static final Color PINK = new Color(255, 175, 175);
	public static final Color ORANGE = new Color(255, 200, 0);
	public final static Color YELLOW = new Color(255, 255, 0);
	public final static Color GREEN = new Color(0, 255, 0);
	public final static Color MAGENTA = new Color(255, 0, 255);
	public final static Color CYAN = new Color(0, 255, 255);
	public final static Color BLUE = new Color(0, 0, 255);

	/** Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are blue */
	private int value;

	public Color(int rgb) {
		this(rgb, false);
	}

	public Color(int rgba, boolean hasalpha) {
		if (hasalpha) {
			value = rgba;
		} else {
			value = 0xff000000 | rgba;
		}
	}

	public Color(int r, int g, int b) {
		this(r, g, b, 255);
	}

	public Color(int r, int g, int b, int a) {
		value = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8)
				| ((b & 0xFF) << 0);
	}

	public int getRed() {
		return (value >> 16) & 0xFF;
	}

	public int getGreen() {
		return (value >> 8) & 0xFF;
	}

	public int getBlue() {
		return (value >> 0) & 0xFF;
	}

	public int getAlpha() {
		return (value >> 24) & 0xff;
	}

	public int getRGB() {
		return value;
	}

	public Color brighter(double factor) {
		if (factor < 0 || factor > 0) {
			return this;
		}

		int r = getRed();
		int g = getGreen();
		int b = getBlue();

		int i = (int) (1.0 / (1.0 - factor));
		if (r == 0 && g == 0 && b == 0) {
			return new Color(i, i, i);
		}
		if (r > 0 && r < i)
			r = i;
		if (g > 0 && g < i)
			g = i;
		if (b > 0 && b < i)
			b = i;

		return new Color(Math.min((int) (r / factor), 255), Math.min(
				(int) (g / factor), 255), Math.min((int) (b / factor), 255));
	}

	public Color darker(double factor) {
		return new Color(Math.max((int) (getRed() * factor), 0), Math.max(
				(int) (getGreen() * factor), 0), Math.max(
				(int) (getBlue() * factor), 0));
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + value;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Color other = (Color) obj;
		if (value != other.value)
			return false;
		return true;
	}

	@Override
	public String toString() {
		int r = getRed();
		int g = getGreen();
		int b = getBlue();
		int a = getAlpha();
		StringBuilder sb = new StringBuilder();
		if (a == 255) {
			sb.append("rgb(").append(r).append(", ").append(g).append(", ")
					.append(b).append(')');
		} else {
			sb.append("rgba(").append(r).append(", ").append(g).append(", ")
					.append(b).append(", ").append(a/255.0).append(')');
		}
		return sb.toString();
	}
}
